package com.edu.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.edu.system.domain.TClass;
import com.edu.system.domain.TTeacher;
import com.edu.system.domain.dto.LessonTimetableDTO;
import com.edu.system.domain.dto.TimetableDO;
import com.edu.system.domain.dto.WeekTimetableDTO;
import com.edu.system.domain.dto.WeekTimetableDTO.Column;
import com.edu.system.domain.dto.WeekTimetableDTO.Timetable;
import com.edu.system.domain.req.WeekTimetableReq;
import com.edu.system.service.ITClassExtService;
import com.edu.system.service.ITClassService;
import com.edu.system.service.ITTeacherExtService;
import com.edu.system.service.ITTeacherService;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import com.edu.common.utils.DateUtils;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import com.edu.system.mapper.TLessonTimetableMapper;
import com.edu.system.domain.TLessonTimetable;
import com.edu.system.service.ITLessonTimetableService;

/**
 * 课Service业务层处理
 * 
 * @author xxxx
 * @date 2024-01-01
 */
@Slf4j
@Service
public class TLessonTimetableServiceImpl implements ITLessonTimetableService 
{
    @Resource
    private TLessonTimetableMapper tLessonTimetableMapper;

    /**
     * 查询课
     * 
     * @param id 课主键
     * @return 课
     */
    @Override
    public TLessonTimetable selectTLessonTimetableById(Long id)
    {
        return tLessonTimetableMapper.selectTLessonTimetableById(id);
    }

    /**
     * 查询课列表
     * 
     * @param tLessonTimetable 课
     * @return 课
     */
    @Override
    public List<TLessonTimetable> selectTLessonTimetableList(TLessonTimetable tLessonTimetable)
    {
        return tLessonTimetableMapper.selectTLessonTimetableList(tLessonTimetable);
    }

    @Override
    public List<LessonTimetableDTO> showTLessonTimetableList(TLessonTimetable t) {
        List<TLessonTimetable> tList = this.selectTLessonTimetableList(t);

        return tList.stream().map(a -> {
            LessonTimetableDTO d = BeanUtil.copyProperties(a, LessonTimetableDTO.class);
            return d;
        }).collect(Collectors.toList());
    }

    /**
     * 新增课
     * 
     * @param tLessonTimetable 课
     * @return 结果
     */
    @Override
    public int insertTLessonTimetable(TLessonTimetable tLessonTimetable)
    {
        tLessonTimetable.setCreateTime(DateUtils.getNowDate());
        return tLessonTimetableMapper.insertTLessonTimetable(tLessonTimetable);
    }

    /**
     * 修改课
     * 
     * @param tLessonTimetable 课
     * @return 结果
     */
    @Override
    public int updateTLessonTimetable(TLessonTimetable tLessonTimetable)
    {
        return tLessonTimetableMapper.updateTLessonTimetable(tLessonTimetable);
    }

    /**
     * 批量删除课
     * 
     * @param ids 需要删除的课主键
     * @return 结果
     */
    @Override
    public int deleteTLessonTimetableByIds(Long[] ids)
    {
        return tLessonTimetableMapper.deleteTLessonTimetableByIds(ids);
    }

    /**
     * 删除课信息
     * 
     * @param id 课主键
     * @return 结果
     */
    @Override
    public int deleteTLessonTimetableById(Long id)
    {
        return tLessonTimetableMapper.deleteTLessonTimetableById(id);
    }

    @Override
    public WeekTimetableDTO buildWeekTimetable(WeekTimetableReq req, Integer tableType) {

        TimetableDO t = new TimetableDO();
        Optional.ofNullable(req.getEid()).ifPresent(t::setTeacherEid);
        Optional.ofNullable(req.getLocationId()).ifPresent(t::setLocationId);

        String[] week = getWeekDays(req.getStartLessonDate());
        t.setStartLessonDate(week[0]);
        t.setEndLessonDate(week[6]);

        List<TLessonTimetable> list = tLessonTimetableMapper.selectTimetableList(t);

        Map<String, Map<String, TLessonTimetable>> collect = list.stream()
            .collect(Collectors.groupingBy(TLessonTimetable::getStartTime,
                Collectors.toMap(a -> DateUtil.formatDate(a.getLessonDate()), m -> m, (x, y) -> x)));
        // 排序
        List<String> startTimeList = collect.entrySet().stream().map(Entry::getKey).sorted()
            .collect(Collectors.toList());

        // 处理课表
        List<Timetable> timetableList = new ArrayList<>();
        startTimeList.forEach(a -> {
            Map<String, TLessonTimetable> map = collect.get(a);
            Timetable tt = new Timetable();
            tt.setStartTime(a);
            tt.setMonday(buildLessonMsg(map.get(week[0]), tableType));
            tt.setTuesday(buildLessonMsg(map.get(week[1]), tableType));
            tt.setWednesday(buildLessonMsg(map.get(week[2]), tableType));
            tt.setThursday(buildLessonMsg(map.get(week[3]), tableType));
            tt.setFriday(buildLessonMsg(map.get(week[4]), tableType));
            tt.setSaturday(buildLessonMsg(map.get(week[5]), tableType));
            tt.setSunday(buildLessonMsg(map.get(week[6]), tableType));
            timetableList.add(tt);
        });

        // 课表字段
        List<Column> columns = new ArrayList<>();
        columns.add(Column.builder().label("时间/日期").prop("startTime").width("150").build());
        for (int i = 0; i< week.length;i++){
            Column column = new Column();
            column.setLabel(this.getWeekStr()[i] + "/" + week[i]);
            column.setProp(this.getFieldName()[i]);
            column.setWidth("150");
            columns.add(column);
        }

        return WeekTimetableDTO.builder()
            .timetableList(timetableList)
            .columns(columns)
            .startLessonDate(week[0])
            .endLessonDate(week[6])
            .build();
    }

    private String buildLessonMsg(TLessonTimetable timetable, Integer tableType){
        log.info(JSONObject.toJSONString(timetable));
        if (timetable == null){
            return "";
        }
        String title = null;
        if (tableType.equals(CLASS_TABLE)){
            title = Optional.ofNullable(timetable.getTeacherName()).orElseGet(()->"");
        }
        if (tableType.equals(TEACHER_TABLE)){
            title = Optional.ofNullable(timetable.getClassName()).orElseGet(() -> "");
        }

        String builder = "【" + title + "】" + "/"
            + timetable.getLessonName() + "/"
            + timetable.getStartTime() + "~" + timetable.getEndTime();
        return builder;
    }

    private String[] getWeekStr(){
        return new String[]{"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"};
    }
    private String[] getFieldName(){
        return new String[]{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"};
    }

    private String[] getWeekDays(String date) {
        // 设置日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        // 获取当前日期
        LocalDate today = LocalDate.now();
        if (date != null){
            today = LocalDate.parse(date);
        }

        // 获取本周的开始日期（星期一）
        LocalDate monday = today.with(DayOfWeek.MONDAY);
        String mondayDate = monday.format(formatter);
        LocalDate tuesday = today.with(DayOfWeek.TUESDAY);
        String tuesdayDate = tuesday.format(formatter);
        LocalDate wednesday = today.with(DayOfWeek.WEDNESDAY);
        String wednesdayDate = wednesday.format(formatter);
        LocalDate thursday = today.with(DayOfWeek.THURSDAY);
        String thursdayDate = thursday.format(formatter);
        LocalDate friday = today.with(DayOfWeek.FRIDAY);
        String fridayDate = friday.format(formatter);
        LocalDate saturday = today.with(DayOfWeek.SATURDAY);
        String saturdayDate = saturday.format(formatter);
        // 获取本周的结束日期（星期天）
        LocalDate sunday = today.with(DayOfWeek.SUNDAY);
        String sundayDate = sunday.format(formatter);

        return new String[]{mondayDate, tuesdayDate, wednesdayDate, thursdayDate, fridayDate, saturdayDate, sundayDate};
    }


}
